package com.genesis.mall.Interception;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.genesis.mall.entity.UmsAdminRoleRelation;
import com.genesis.mall.entity.UmsResource;
import com.genesis.mall.entity.UmsRoleResourceRelation;
import com.genesis.mall.service.IUmsAdminRoleRelationService;
import com.genesis.mall.service.IUmsResourceService;
import com.genesis.mall.service.IUmsRoleResourceRelationService;
import com.genesis.mall.utils.TokenUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class TokenInterception implements HandlerInterceptor {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private IUmsAdminRoleRelationService umsAdminRoleRelationService;

    @Autowired
    private IUmsRoleResourceRelationService roleResourceRelationService;

    @Autowired
    private IUmsResourceService resourceService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");
        String[] split = token.split(" ");
        token = split[1];
        Claims claims = TokenUtil.getClaims(token);
        String uuid = (String) claims.get("uuid");
        if (uuid == null){
            return true;
        }
        String redisKey = split[0] + "_" + uuid;
        log.info(redisKey);
        String uri = request.getRequestURI().substring(1);
        uri = uri.substring(uri.indexOf("/"));

        String redisToken = redisTemplate.opsForValue().get(redisKey);

        if (redisToken == null || (!redisToken.equals(token))) {
            throw  new RuntimeException();
        }

        //通过Token获得id
        Integer adminId = (Integer) claims.get("adminId");
        LambdaQueryWrapper<UmsAdminRoleRelation> lqw = new LambdaQueryWrapper<>();
        lqw.eq(UmsAdminRoleRelation::getAdminId, adminId);
        List<UmsAdminRoleRelation> adminRoleRelations = umsAdminRoleRelationService.list(lqw);
        List<Long> roleIds = adminRoleRelations.stream().map(UmsAdminRoleRelation::getRoleId).collect(Collectors.toList());
        LambdaQueryWrapper<UmsRoleResourceRelation> roleResource = new LambdaQueryWrapper<>();
        for (Long roleId : roleIds) {
            roleResource.or().eq(UmsRoleResourceRelation::getRoleId,roleId);
        }
        List<UmsRoleResourceRelation> relations = roleResourceRelationService.list(roleResource);

        List<String> urlList = relations.stream().map(relation -> {
            UmsResource resource = resourceService.getById(relation);
            return resource.getUrl();
        }).collect(Collectors.toList());

        boolean flag = false;

        for (String s : urlList) {
            if (s.contains(uri)){
                flag = true;
                break;
            }
        }
        if (!flag){
            throw new RuntimeException();
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
